﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Ex03.GarageLogic
{
    /// <summary>
    /// the Garage class connect the UI with the Logic, its has a Dictionary of VehicleInGarage by the license number
    /// </summary>
    public class Garage
    {
        private Dictionary<string, VehicleInGarage> m_VehiclesInGarage = null;

        public Garage()
        {
            m_VehiclesInGarage = new Dictionary<string, VehicleInGarage>();
        }

        /// <summary>
        /// check if a VehicleInGarage with the lisence number exists at the garage
        /// </summary>
        /// <param name="i_StringLisenceNumber">lisence number</param>
        /// <returns>true if VehicleInGarage with the lisence number exists at the garage</returns>
        public bool IsVehicleExist(string i_StringLisenceNumber)
        {
            return m_VehiclesInGarage.ContainsKey(i_StringLisenceNumber);
        }

        /// <summary>
        /// change the VehicleInGarage state to i_VehicleNewState according to the given lisence number
        /// </summary>
        /// <param name="i_StringLisenceNumber">lisence number</param>
        /// <param name="i_VehicleNewState">the new VehicleInGarage state</param>
        public void ChangeVehicleState(string i_StringLisenceNumber, eStageOfTreatment i_VehicleNewState)
        {
            VehicleInGarage changeVehicleState = null;

            changeVehicleState = getVehicleByLisenceNumber(i_StringLisenceNumber);
            changeVehicleState.StageOfTreatment = i_VehicleNewState;
        }
       
        /// <summary>
        /// create a VehicleGenerator using VehicleGenerator with the given params
        /// </summary>
        /// <param name="i_VehicleType"></param>
        /// <param name="i_EnergySourceType"></param>
        /// <param name="i_ModelNameForVehicle"></param>
        /// <param name="i_StringLisenceNumber"></param>
        /// <param name="i_WheelManufacturerName"></param>
        public void CreateNewVehicleInGarage(eVehicleType i_VehicleType, eEnergyType i_EnergySourceType, string i_ModelNameForVehicle, string i_StringLisenceNumber, string i_WheelManufacturerName)
        {
            Vehicle newVehicle = VehicleGenerator.GenerateVehicle(i_VehicleType, i_EnergySourceType, i_ModelNameForVehicle, i_StringLisenceNumber, i_WheelManufacturerName);
            VehicleInGarage newVehicleInGaage = new VehicleInGarage(newVehicle);

            m_VehiclesInGarage.Add(newVehicle.VehicleLicenseNumber, newVehicleInGaage);
            newVehicle.CalculateEnergyLeftInEnergySource();
        }

        /// <summary>
        /// Set Owner Name And Phone To VehicleInGarage by the given params
        /// </summary>
        /// <param name="i_StringLisenceNumber"></param>
        /// <param name="i_OwnerName"></param>
        /// <param name="i_OwnerPhoneNumber"></param>
        public void SetOwnerNameAndPhoneToVehicleInGarage(string i_StringLisenceNumber, string i_OwnerName, string i_OwnerPhoneNumber)
        {
            VehicleInGarage updatedVehicle = null;

            updatedVehicle = getVehicleByLisenceNumber(i_StringLisenceNumber);
            updatedVehicle.OwnerName = i_OwnerName;
            updatedVehicle.OwnerPhoneNumber = i_OwnerPhoneNumber;
        }

        /// <summary>
        /// return all or some of the kicense numbers of the vehicles in the garge (by i_UserTreatmeantState)
        /// </summary>
        /// <param name="i_UserTreatmeantState">the state of the vehicles</param>
        /// <param name="i_ReturnAllLisences">if true then return All the vehicles in the garage</param>
        /// <returns>a list of all the lisence numbers of the sutiable vehicles</returns>
        public List<string> GetListOfLisenceNumberByTreatmeantState(eStageOfTreatment i_UserTreatmeantState, bool i_ReturnAllLisences)
        {
            List<string> listOfLisenceNumber = new List<string>();

            foreach (KeyValuePair<string, VehicleInGarage> vehicleInGarage in m_VehiclesInGarage)
            {
                if (vehicleInGarage.Value.StageOfTreatment == i_UserTreatmeantState || i_ReturnAllLisences)
                {
                    listOfLisenceNumber.Add(vehicleInGarage.Key);
                }
            }

            return listOfLisenceNumber;
        }

        /// <summary>
        /// pump all of the wheels of the vehicle to max
        /// </summary>
        /// <param name="i_StringLisenceNumber">the vehicle to pump its wheels</param>
        public void PumpVehicleWheelsToMax(string i_StringLisenceNumber)
        {
            VehicleInGarage vehicleForPump = null;

            vehicleForPump = getVehicleByLisenceNumber(i_StringLisenceNumber);
            foreach (Wheel whell in vehicleForPump.Vehicle.WheelsArray)
	        {
                float airToPump = whell.MaxAirPressureByManufacturer - whell.CurrentAirPressure;

                whell.PumpWhell(airToPump);
	        }                
        }

        private VehicleInGarage getVehicleByLisenceNumber(string i_StringLisenceNumber)
        {
            VehicleInGarage vehicleByLisence = null;
            bool vehicleFound = m_VehiclesInGarage.TryGetValue(i_StringLisenceNumber, out vehicleByLisence);

            if (!vehicleFound)
            {
                throw new Exception("No vehicle exist in the garage!");
            }

            return vehicleByLisence;
        }

        /// <summary>
        /// increase the energy of a fuelpowerd vehicle
        /// throw ArgumentException if the vehicle energy source isn't fuel
        /// </summary>
        /// <param name="i_StringLisenceNumber"></param>
        /// <param name="i_HowMuchFuelToFuel"></param>
        /// <param name="i_TypeOfFuel"></param>
        public void FuelFueledPowerdVehicle(string i_StringLisenceNumber, float i_HowMuchFuelToFuel, eFuelType i_TypeOfFuel)
        {
            VehicleInGarage vehicleForFuel = null;

            vehicleForFuel = getVehicleByLisenceNumber(i_StringLisenceNumber);
            if (vehicleForFuel.Vehicle.isPowerdBy(typeof(FuelPowered)))
            {
                FuelPowered tankOfVehicleToFuel = vehicleForFuel.Vehicle.EnergySource as FuelPowered;

                tankOfVehicleToFuel.FuelTheTank(i_TypeOfFuel, i_HowMuchFuelToFuel);
                vehicleForFuel.Vehicle.CalculateEnergyLeftInEnergySource();
            }
            else
            {
                throw new ArgumentException("Vehicle is not powered by fuel!");     
            }
        }

        /// <summary>
        /// increase the energy of a electricitypowerd vehicle
        /// throw ArgumentException if the vehicle energy source isn't electricity
        /// </summary>
        /// <param name="i_StringLisenceNumber"></param>
        /// <param name="i_MinutesOfChargeTime"></param>
        public void ChargeBattery(string i_StringLisenceNumber, float i_MinutesOfChargeTime)
        {
            VehicleInGarage vehicleForCharge = null;

            vehicleForCharge = getVehicleByLisenceNumber(i_StringLisenceNumber);
            if (vehicleForCharge.Vehicle.isPowerdBy(typeof(ElectricityPowered)))
            {
                ElectricityPowered batteryOfVehicleToCharge = vehicleForCharge.Vehicle.EnergySource as ElectricityPowered;

                batteryOfVehicleToCharge.ChargeBattery(i_MinutesOfChargeTime);
                vehicleForCharge.Vehicle.CalculateEnergyLeftInEnergySource();
            }
            else
            {
                throw new ArgumentException("Vehivle is not powered by electricity!");
            }
        }

        /// <summary>
        /// commit the toString of the VehicleInGarage
        /// </summary>
        /// <param name="i_StringLisenceNumber"></param>
        /// <returns>string with all the info of the VehicleInGarage</returns>
        public string PrintInfoOfVehicle(string i_StringLisenceNumber)
        {
            VehicleInGarage vehicleForInfo = null;

            vehicleForInfo = getVehicleByLisenceNumber(i_StringLisenceNumber);
            return vehicleForInfo.ToString();
        }

        /// <summary>
        /// get the Vehicle.GetSpecificProperties
        /// </summary>
        /// <param name="i_StringLisenceNumber"></param>
        /// <returns>list with the request specific properties of a vehicle</returns>
        public List<string> GetPropertiesByVehicleLicense(string i_StringLisenceNumber)
        {
            VehicleInGarage vehicleForProperties = null;
            List<string> listOfVehicleProperties = null;

            vehicleForProperties = getVehicleByLisenceNumber(i_StringLisenceNumber);
            listOfVehicleProperties = vehicleForProperties.Vehicle.GetSpecificProperties();

            return listOfVehicleProperties;
        }

        /// <summary>
        /// set the Vehicle.SetSpecificProperties
        /// </summary>
        /// <param name="i_StringLisenceNumber"></param>
        /// <param name="i_ListOfSpecificVehiclePropertiesFromUser">list of specific parms for the specific vehicle</param>
        public void SetPropertiesByVehicleLicense(string i_StringLisenceNumber, List<string> i_ListOfSpecificVehiclePropertiesFromUser)
        {
            VehicleInGarage vehicleForProperties = null;

            vehicleForProperties = getVehicleByLisenceNumber(i_StringLisenceNumber);
            vehicleForProperties.Vehicle.SetSpecificProperties(i_ListOfSpecificVehiclePropertiesFromUser);
        }
    }
}
